<script setup>
import { ref, watch, nextTick } from 'vue'
import { marked } from 'marked'
import hljs from 'highlight.js'
import Message from './Message.vue'
import TrendingTopics from './TrendingTopics.vue'
import FileUploader from './FileUploader.vue'

const props = defineProps({
  currentPage: {
    type: String,
    required: true
  },
  messages: {
    type: Array,
    default: () => []
  },
  conversationId: {
    type: String,
    required: true
  }
})

const emit = defineEmits(['update-messages', 'loading-change', 'show-auth'])

const localMessages = ref([])
const userInput = ref('')
const fileInput = ref(null)
const selectedModel = ref('douban')
const errorMessage = ref('')
const selectedFile = ref(null)

// API 基础URL
// API 基础URL - 更灵活的获取方式
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 
                     (window.location.hostname === 'localhost' ? 'http://localhost:5000/api' : 
                     `${window.location.protocol}//${window.location.hostname}:5000/api`)

// 用于API请求的重试函数
const fetchWithRetry = async (url, options, maxRetries = 3, delay = 1000) => {
  let lastError
  
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fetch(url, options)
    } catch (error) {
      console.log(`请求失败，尝试重试 ${i+1}/${maxRetries}...`)
      lastError = error
      
      // 最后一次尝试失败，直接抛出错误
      if (i === maxRetries - 1) throw error
      
      // 等待一段时间后重试
      await new Promise(resolve => setTimeout(resolve, delay))
      // 每次重试增加延迟
      delay *= 1.5
    }
  }
}

// 可用的模型列表
const availableModels = [
  { id: 'douban', name: '豆包', icon: 'fa-brain' },
  { id: 'qianwen', name: '通义千问', icon: 'fa-lightbulb' }
]

// 检查用户是否已登录
const checkUserLoggedIn = () => {
  const token = localStorage.getItem('token')
  return !!token
}

// 同步外部传入的消息
watch(() => props.messages, (newMessages) => {
  localMessages.value = newMessages
}, { immediate: true })

// 监听消息列表变化，自动滚动到底部
watch(localMessages, () => {
  nextTick(() => {
    const container = document.querySelector('.chat-messages')
    if (container) {
      container.scrollTop = container.scrollHeight
    }
  })
}, { deep: true, immediate: true })  // 添加immediate: true确保首次加载时也执行

// 配置 marked
marked.setOptions({
  highlight: function(code, lang) {
    if (lang && hljs.getLanguage(lang)) {
      return hljs.highlight(code, { language: lang }).value
    }
    return hljs.highlightAuto(code).value
  },
  breaks: true
})

// 添加模型问题判断函数
const isModelQuestion = (message) => {
  const modelKeywords = [
    '你是什么模型',
    '你是谁',
    '你是什么',
    '你的身份',
    '你的类型',
    '你的模型',
    '你的版本',
    '你叫什么',
    '你的名字',
    '介绍一下你自己',
    '你能做什么',
    '你的功能',
    '你基于什么',
    '你是基于',
    '你是哪个模型',
    '你是什么助手',
    '你是什么AI'
  ]
  return modelKeywords.some(keyword => message.toLowerCase().includes(keyword.toLowerCase()))
}

// 处理消息发送
const handleSendMessage = async (message) => {
  if (!message.trim()) return
  
  // 检查用户是否已登录
  if (!checkUserLoggedIn()) {
    // 如果未登录，提示用户登录
    errorMessage.value = '请先登录后再使用此功能'
    
    // 触发显示登录弹窗事件
    emit('show-auth')
    
    // 添加系统提示消息
    localMessages.value.push({
      type: 'assistant',
      content: '请先登录后再使用此功能。',
      timestamp: new Date().toISOString()
    })
    
    // 更新父组件的消息
    emit('update-messages', localMessages.value)
    return
  }
  
  // 先添加用户消息到对话历史
  localMessages.value.push({
    type: 'user',
    content: message,
    timestamp: new Date().toISOString()
  })
  
  // 更新父组件的消息
  emit('update-messages', localMessages.value)
  
  // 清空输入框
  userInput.value = ''
  errorMessage.value = ''

  try {
    // 根据当前页面类型处理不同的请求
    if (props.currentPage === 'meeting') {
      // 会议处理
      await askMeetingQuestion(message)
    } else if (props.currentPage === 'chat') {
      // 智能对话
      await sendChatRequest(message)
    } else if (props.currentPage === 'knowledge') {
      // 知识库问答
      await sendKnowledgeRequest(message)
    } else if (props.currentPage === 'weather') {
      // 天气查询
      await sendWeatherRequest(message)
    } else if (props.currentPage === 'task') {
      // 任务管理
      await sendTaskRequest(message)
    } else if (props.currentPage === 'health') {
      // 健康助手
      await sendHealthRequest(message)
    }
  } catch (error) {
    console.error('Error sending message:', error)
    errorMessage.value = '消息发送失败，请稍后再试'
    
    localMessages.value.push({
      type: 'assistant',
      content: '抱歉，发生了错误。请稍后再试。',
      timestamp: new Date().toISOString()
    })
    
    emit('update-messages', localMessages.value)
  }
}

// 智能对话请求
const sendChatRequest = async (message) => {
  const token = localStorage.getItem('token')
  
  // 添加一个空的消息占位，稍后会更新它
  const messageIndex = localMessages.value.length;
  localMessages.value.push({
    type: 'assistant',
    content: '',
    timestamp: new Date().toISOString(),
    isStreaming: true
  });
  
  // 更新父组件消息
  emit('update-messages', localMessages.value);
  
  // 创建请求对象
  const requestData = {
    message,
    conversation_id: props.conversationId,
    model: selectedModel.value,
    page_type: props.currentPage
  };
  
  try {
    // 发送POST请求获取流式响应
    const response = await fetch(`${API_BASE_URL}/chat/stream`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
      body: JSON.stringify(requestData)
    });
    
    // 检查响应状态
  if (!response.ok) {
      const errorData = await response.json();
      throw new Error(errorData.error || '流式请求失败');
    }
    
    // 处理流式响应
    await processStreamResponse(response, messageIndex);
    
  } catch (error) {
    console.error('流式请求错误:', error);
    
    // 安全地更新错误消息
    if (messageIndex < localMessages.value.length) {
      localMessages.value[messageIndex].content = `抱歉，发生了错误: ${error.message}`;
      localMessages.value[messageIndex].isStreaming = false;
      localMessages.value[messageIndex].isError = true;
      
      // 更新父组件消息
      emit('update-messages', localMessages.value);
    } else {
      // 如果消息索引无效，创建一个新的错误消息
      localMessages.value.push({
        type: 'assistant',
        content: `抱歉，发生了错误: ${error.message}`,
        timestamp: new Date().toISOString(),
        isError: true
      });
      emit('update-messages', localMessages.value);
    }
    return `抱歉，发生了错误: ${error.message}`;
  }
}

// 知识问答请求
const sendKnowledgeRequest = async (message) => {
  const token = localStorage.getItem('token')
  
  // 获取用户选择的知识库ID
  const knowledgeBaseId = localStorage.getItem('selectedKnowledgeBase')
  
  if (!knowledgeBaseId) {
    return '请先上传PDF、TXT或DOCX文件创建知识库。点击右上角的文件上传按钮上传文档。'
  }
  
  // 添加一个空的消息占位，稍后会更新它
  const messageIndex = localMessages.value.length;
  localMessages.value.push({
    type: 'assistant',
    content: '',
    timestamp: new Date().toISOString(),
    isStreaming: true,
    sources: [] // 初始化空的来源数组
  });
  
  // 更新父组件消息
  emit('update-messages', localMessages.value);
  
  try {
    console.log(`正在连接知识库API: ${API_BASE_URL}/knowledge/query`);
    
    // 先发送非流式请求获取完整响应（包括来源）
    const fullResponse = await fetchWithRetry(`${API_BASE_URL}/knowledge/query`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
      },
      body: JSON.stringify({
        query: message,
        kb_id: knowledgeBaseId
      })
    });
    
    if (!fullResponse.ok) {
      const errorData = await fullResponse.json();
      throw new Error(errorData.error || '知识库查询失败');
    }
    
    const fullData = await fullResponse.json();
    const sources = fullData.sources || [];
    
    // 发送流式请求
    console.log(`正在连接流式API: ${API_BASE_URL}/knowledge/query/stream`);
    const response = await fetchWithRetry(`${API_BASE_URL}/knowledge/query/stream`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
      },
      body: JSON.stringify({
        query: message,
        kb_id: knowledgeBaseId
      })
    });
  
    if (!response.ok) {
      // 如果流式API不可用，回退到普通API
      if (response.status === 404) {
        console.log('流式API不可用，使用普通API响应');
        // 移除流式消息占位
        localMessages.value.pop();
        emit('update-messages', localMessages.value);
        
        // 使用普通API响应
        localMessages.value.push({
          type: 'assistant',
          content: fullData.response,
          timestamp: new Date().toISOString(),
          sources: sources
        });
        emit('update-messages', localMessages.value);
        return fullData.response;
      } else {
        const errorData = await response.json();
        throw new Error(errorData.error || '流式知识库查询失败');
      }
    }
    
    // 创建一个reader来处理流式数据
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let buffer = '';
    let fullStreamResponse = ''; // 用于保存完整响应
    
    // 读取数据流
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;
      
      // 解码当前块并添加到缓冲区
      buffer += decoder.decode(value, { stream: true });
      
      // 处理缓冲区中的所有完整事件
      const lines = buffer.split('\n\n');
      buffer = lines.pop() || ''; // 保留最后一个不完整的块
      
      for (const line of lines) {
        if (line.startsWith('data: ')) {
          try {
            const data = JSON.parse(line.substring(6));
            
            if (data.chunk) {
              // 检查消息是否仍然存在
              if (messageIndex < localMessages.value.length) {
                // 更新消息内容
                localMessages.value[messageIndex].content += data.chunk;
                localMessages.value[messageIndex].isStreaming = true;
                fullStreamResponse += data.chunk;
                
                // 更新父组件消息
                emit('update-messages', localMessages.value);
              }
            } else if (data.done) {
              // 流式输出完成
              if (messageIndex < localMessages.value.length) {
                localMessages.value[messageIndex].isStreaming = false;
                // 添加来源信息
                localMessages.value[messageIndex].sources = sources;
                emit('update-messages', localMessages.value);
              }
              return data.full_response || fullStreamResponse;
            } else if (data.error) {
              throw new Error(data.error);
            }
          } catch (e) {
            console.error('解析事件数据失败:', e, line);
          }
        }
      }
    }
    
    // 如果到这里，说明流结束但没有收到done事件
    if (messageIndex < localMessages.value.length) {
      localMessages.value[messageIndex].isStreaming = false;
      // 添加来源信息
      localMessages.value[messageIndex].sources = sources;
      emit('update-messages', localMessages.value);
    }
    return fullStreamResponse;
    
  } catch (error) {
    console.error('Knowledge request error:', error);
    
    // 如果是连接错误，提供更具体的错误信息
    let errorMessage = error.message;
    if (error.message.includes('Connection error') || error.message.includes('Failed to fetch')) {
      errorMessage = '连接到服务器失败，请检查服务器是否运行或网络连接是否正常。API地址: ' + API_BASE_URL;
    }
    
    // 安全地更新错误消息
    if (messageIndex < localMessages.value.length) {
      localMessages.value[messageIndex].content = `抱歉，知识库查询失败: ${errorMessage}`;
      localMessages.value[messageIndex].isStreaming = false;
      localMessages.value[messageIndex].isError = true;
      
      // 更新父组件消息
      emit('update-messages', localMessages.value);
    } else {
      // 如果消息索引无效，创建一个新的错误消息
      localMessages.value.push({
        type: 'assistant',
        content: `抱歉，知识库查询失败: ${errorMessage}`,
        timestamp: new Date().toISOString(),
        isError: true
      });
      emit('update-messages', localMessages.value);
    }
    return `抱歉，知识库查询失败: ${errorMessage}`;
  }
}

// 天气查询请求
const sendWeatherRequest = async (message) => {
  try {
    // 添加一个空的消息占位，稍后会更新它
    const messageIndex = localMessages.value.length;
    localMessages.value.push({
      type: 'assistant',
      content: '',
      timestamp: new Date().toISOString(),
      isStreaming: true
    });
    
    // 更新父组件消息
    emit('update-messages', localMessages.value);
    
  // 假设message是城市名称
  const response = await fetch(`${API_BASE_URL}/weather?city=${encodeURIComponent(message)}`)
  
  if (!response.ok) {
      const errorData = await response.json()
      localMessages.value[messageIndex].content = `无法获取天气信息：${errorData.error || '服务器错误'}`;
      localMessages.value[messageIndex].isStreaming = false;
      localMessages.value[messageIndex].isError = true;
      emit('update-messages', localMessages.value);
      return `无法获取天气信息：${errorData.error || '服务器错误'}`
  }
  
  const data = await response.json()
  
  // 格式化天气信息
  if (data.error) {
      localMessages.value[messageIndex].content = `无法获取天气信息：${data.error}`;
      localMessages.value[messageIndex].isStreaming = false;
      localMessages.value[messageIndex].isError = true;
      emit('update-messages', localMessages.value);
    return `无法获取天气信息：${data.error}`
  }
  
  let weatherInfo = `## ${data.city}天气预报\n\n`
  
    // 添加实时天气信息
    if (data.live) {
      weatherInfo += '### 实时天气\n\n'
      weatherInfo += `- 天气: ${data.live.weather}\n`
      weatherInfo += `- 温度: ${data.live.temperature}°C\n`
      weatherInfo += `- 湿度: ${data.live.humidity}%\n`
      weatherInfo += `- 风向: ${data.live.winddirection}风 ${data.live.windpower}级\n`
      weatherInfo += `- 更新时间: ${data.live.reporttime}\n\n`
    }
    
    // 添加天气预报信息
  if (data.casts && data.casts.length > 0) {
      weatherInfo += '### 未来天气预报\n\n'
    
    data.casts.forEach((cast, index) => {
      weatherInfo += `**${cast.date}**\n`
      weatherInfo += `- 白天天气: ${cast.dayweather}, ${cast.daytemp}°C\n`
      weatherInfo += `- 夜间天气: ${cast.nightweather}, ${cast.nighttemp}°C\n`
      weatherInfo += `- 风向: ${cast.daywind}风 ${cast.daypower}级\n\n`
    })
  }
    
    // 使用打字机效果显示天气信息
    await simulateTypingEffect(messageIndex, weatherInfo);
  
  return weatherInfo
  } catch (error) {
    console.error('Weather API error:', error)
    return `获取天气信息失败，请检查输入的城市名称是否正确，或者稍后再试。`
  }
}

// 任务管理请求
const sendTaskRequest = async (message) => {
  const token = localStorage.getItem('token')
  
  try {
    // 添加一个空的消息占位，稍后会更新它
    const messageIndex = localMessages.value.length;
    localMessages.value.push({
      type: 'assistant',
      content: '',
      timestamp: new Date().toISOString(),
      isStreaming: true
    });
    
    // 更新父组件消息
    emit('update-messages', localMessages.value);
    
    // 获取当前日期时间，用于实时日期处理
    const now = new Date();
    const currentDateStr = now.toISOString().split('T')[0]; // 当前日期 YYYY-MM-DD
    
    // 使用LLM分析任务请求（非流式）
  const response = await fetch(`${API_BASE_URL}/chat`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({
        message: `请分析以下任务请求，并以JSON格式返回任务信息。请提取标题、描述、截止日期（如果有）。
        截止日期请使用YYYY-MM-DD HH:MM:SS格式，例如${currentDateStr} 15:30:00表示${currentDateStr}下午3点30分。
        返回的JSON必须包含title字段，可以包含description、due_date和send_email字段。
        send_email字段为布尔值，表示是否需要发送邮件提醒，默认为true。
        原始请求：${message}
        
        今天的日期是：${currentDateStr}`,
      conversation_id: 'task-analysis',
      model: selectedModel.value
    })
  })
  
  if (!response.ok) {
      throw new Error('任务分析失败')
    }
    
    const responseData = await response.json();
    const llmResponse = responseData.response;
    
    try {
      // 尝试从响应中提取JSON
      let taskInfoStr = '';
      
      // 尝试不同的JSON提取模式
      const jsonPattern1 = /```json\n([\s\S]*?)\n```/;  // 标准Markdown代码块格式
      const jsonPattern2 = /```([\s\S]*?)```/;          // 无语言标识的代码块
      const jsonPattern3 = /\{[\s\S]*?\}/;              // 直接查找JSON对象
      
      let match = llmResponse.match(jsonPattern1);
      if (match && match[1]) {
        taskInfoStr = match[1].trim();
      } else {
        match = llmResponse.match(jsonPattern2);
        if (match && match[1]) {
          taskInfoStr = match[1].trim();
        } else {
          match = llmResponse.match(jsonPattern3);
          if (match) {
            taskInfoStr = match[0].trim();
          }
        }
      }
      
      if (!taskInfoStr) {
        // 更新消息内容为错误信息
        localMessages.value[messageIndex].content = '我无法解析您的任务请求。请尝试更清晰地描述任务，包括标题、描述和截止日期（可选）。';
        localMessages.value[messageIndex].isStreaming = false;
        emit('update-messages', localMessages.value);
        return '我无法解析您的任务请求。请尝试更清晰地描述任务，包括标题、描述和截止日期（可选）。';
      }
      
      console.log('提取的任务信息JSON字符串:', taskInfoStr)
      
      // 解析JSON
      const taskInfo = JSON.parse(taskInfoStr)
      
      // 验证必要字段
      if (!taskInfo.title) {
        // 更新消息内容为错误信息
        localMessages.value[messageIndex].content = '任务必须包含标题。请重新描述您的任务。';
        localMessages.value[messageIndex].isStreaming = false;
        emit('update-messages', localMessages.value);
        return '任务必须包含标题。请重新描述您的任务。';
      }
      
      // 处理日期格式
      if (taskInfo.due_date && !taskInfo.due_date.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/)) {
        // 尝试转换常见的日期表达方式
        const tomorrow = new Date();
        tomorrow.setDate(tomorrow.getDate() + 1);
        
        if (taskInfo.due_date.includes('明天') || taskInfo.due_date.includes('tomorrow')) {
          // 如果包含"明天"，设置为明天的日期
          const timeMatch = taskInfo.due_date.match(/(\d{1,2})[点|:时](\d{0,2})/);
          let hours = 9; // 默认早上9点
          let minutes = 0;
          
          if (timeMatch) {
            hours = parseInt(timeMatch[1]);
            minutes = timeMatch[2] ? parseInt(timeMatch[2]) : 0;
            
            // 处理下午时间
            if (taskInfo.due_date.includes('下午') || taskInfo.due_date.includes('午后') || 
                taskInfo.due_date.includes('晚上') || taskInfo.due_date.includes('pm')) {
              if (hours < 12) hours += 12;
            }
          }
          
          tomorrow.setHours(hours, minutes, 0);
          taskInfo.due_date = tomorrow.toISOString().replace('T', ' ').substring(0, 19);
        } else {
          // 其他日期表达方式处理
          console.warn('日期格式不符合要求，使用原始值:', taskInfo.due_date);
        }
      }
      
      // 添加发送邮件选项
      if (!taskInfo.send_email) {
        taskInfo.send_email = true; // 默认发送邮件提醒
      }
    
    // 创建任务
    const createResponse = await fetch(`${API_BASE_URL}/tasks`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
      },
      body: JSON.stringify(taskInfo)
    })
    
    if (!createResponse.ok) {
          const errorData = await createResponse.json().catch(() => ({}))
          throw new Error(errorData.error || '任务创建失败')
      }
      
      const createData = await createResponse.json();
      let responseMessage = `✅ 任务已创建：${taskInfo.title}\n\n📝 描述：${taskInfo.description || '无'}\n\n⏰ 截止日期：${taskInfo.due_date || '无'}`;
      
      // 添加邮件提醒信息
      if (taskInfo.send_email) {
        responseMessage += '\n\n✉️ 系统将在截止时间发送邮件提醒';
      }
      
      // 模拟流式输出
      await simulateTypingEffect(messageIndex, responseMessage);
      
      return responseMessage;
    } catch (parseError) {
      console.error('Error parsing task:', parseError);
      // 更新消息内容为错误信息
      localMessages.value[messageIndex].content = `任务解析失败：${parseError.message}。请尝试更清晰地描述任务，包括标题、描述和截止日期（可选）。`;
      localMessages.value[messageIndex].isStreaming = false;
      localMessages.value[messageIndex].isError = true;
      emit('update-messages', localMessages.value);
      return `任务解析失败：${parseError.message}。请尝试更清晰地描述任务，包括标题、描述和截止日期（可选）。`;
    }
  } catch (error) {
    console.error('Task request error:', error);
    return `任务创建失败：${error.message}。请稍后再试。`;
  }
}

// 模拟打字机效果的函数 - 进一步优化速度
const simulateTypingEffect = async (messageIndex, content, typingSpeed = 2) => {
  if (messageIndex >= localMessages.value.length) {
    console.error('Invalid message index');
    return;
  }
  
  // 清空当前内容
  localMessages.value[messageIndex].content = '';
  localMessages.value[messageIndex].isStreaming = true;
  emit('update-messages', [...localMessages.value]);
  
  // 使用更大的块更新，大幅减少渲染次数
  let currentText = '';
  const chunkSize = 20; // 每次添加20个字符
  
  for (let i = 0; i < content.length; i += chunkSize) {
    // 添加一大块字符
    const end = Math.min(i + chunkSize, content.length);
    currentText += content.substring(i, end);
    localMessages.value[messageIndex].content = currentText;
    
    // 更新UI
    emit('update-messages', [...localMessages.value]);
    
    // 极短的延迟
    await new Promise(resolve => setTimeout(resolve, typingSpeed));
    
    // 只在处理了大量文本后滚动
    if (i % 100 === 0) {
      await nextTick(() => {
        const container = document.querySelector('.chat-messages');
        if (container) {
          container.scrollTop = container.scrollHeight;
        }
      });
    }
  }
  
  // 完成打字
  localMessages.value[messageIndex].isStreaming = false;
  emit('update-messages', [...localMessages.value]);
  
  // 最终滚动
  await nextTick(() => {
    const container = document.querySelector('.chat-messages');
    if (container) {
      container.scrollTop = container.scrollHeight;
    }
  });
}

// 健康助手请求
const sendHealthRequest = async (message) => {
  const token = localStorage.getItem('token')
  
  // 健康助手使用特定的提示词模板
  const healthPrompt = `
  你是一个专业的健康顾问AI助手。请根据以下用户的健康问题提供建议。
  请注意：
  1. 明确表示你不是医生，不能替代专业医疗建议
  2. 提供科学、准确的健康信息
  3. 对于严重的健康问题，建议用户咨询医生
  4. 避免做出确切的诊断
  5. 提供生活方式和预防建议
  
  用户问题: ${message}
  `
  
  // 添加一个空的消息占位，稍后会更新它
  const messageIndex = localMessages.value.length;
  localMessages.value.push({
    type: 'assistant',
    content: '',
    timestamp: new Date().toISOString(),
    isStreaming: true
  });
  
  // 更新父组件消息
  emit('update-messages', localMessages.value);
  
  try {
    // 发送流式请求
    const response = await fetch(`${API_BASE_URL}/chat/stream`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({
      message: healthPrompt,
      conversation_id: 'health-assistant',
      model: selectedModel.value
    })
    });
  
  if (!response.ok) {
      throw new Error('Health request failed');
    }
    
    // 使用统一的流式处理函数
    return await processStreamResponse(response, messageIndex);
    
  } catch (error) {
    console.error('Health request error:', error);
    
    // 安全地更新错误消息
    if (messageIndex < localMessages.value.length) {
      localMessages.value[messageIndex].content = `抱歉，健康咨询失败: ${error.message}`;
      localMessages.value[messageIndex].isStreaming = false;
      localMessages.value[messageIndex].isError = true;
      
      // 更新父组件消息
      emit('update-messages', localMessages.value);
    } else {
      // 如果消息索引无效，创建一个新的错误消息
      localMessages.value.push({
        type: 'assistant',
        content: `抱歉，健康咨询失败: ${error.message}`,
        timestamp: new Date().toISOString(),
        isError: true
      });
      emit('update-messages', localMessages.value);
    }
    return `抱歉，健康咨询失败: ${error.message}`;
  }
}

// 处理流式响应的通用函数
const processStreamResponse = async (response, messageIndex, sources = []) => {
  console.log(`开始处理流式响应，消息索引: ${messageIndex}, 当前页面: ${props.currentPage}`)
  
  try {
    // 创建一个reader来处理流式数据
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let buffer = '';
    let fullResponse = ''; // 用于保存完整响应
    let accumulatedChunks = ''; // 累积的文本块
    let updateCounter = 0; // 更新计数器
    let receivedAnyContent = false; // 标记是否收到任何内容
    
    // 确认消息索引有效
    if (messageIndex >= localMessages.value.length) {
      console.error(`无效的消息索引: ${messageIndex}, 消息数组长度: ${localMessages.value.length}`)
      // 创建一个新的消息而不是抛出错误
      messageIndex = localMessages.value.length;
      localMessages.value.push({
        type: 'assistant',
        content: '',
        timestamp: new Date().toISOString(),
        isStreaming: true
      });
      emit('update-messages', localMessages.value);
      console.log(`创建了新的消息，新索引: ${messageIndex}`);
    }
    
    console.log(`初始消息内容: "${localMessages.value[messageIndex].content}"`);
    
    // 读取数据流
    try {
      console.log('开始读取流数据...');
      while (true) {
        const { done, value } = await reader.read();
        if (done) {
          console.log('流读取完成');
          break;
        }
        
        // 解码当前块并添加到缓冲区
        const chunk = decoder.decode(value, { stream: true });
        buffer += chunk;
        console.log(`接收到数据块，长度: ${chunk.length} 字符`);
        
        // 处理缓冲区中的所有完整事件
        const lines = buffer.split('\n\n');
        buffer = lines.pop() || ''; // 保留最后一个不完整的块
        
        if (lines.length > 0) {
          console.log(`处理 ${lines.length} 个完整事件`);
        }
        
        for (const line of lines) {
          if (line.startsWith('data: ')) {
            try {
              const dataStr = line.substring(6);
              // 检查JSON格式是否有效
              if (!dataStr.trim()) {
                console.warn('收到空数据块，跳过');
                continue;
              }
              
              // 尝试解析JSON
              const data = JSON.parse(dataStr);
              console.log(`解析的数据: ${JSON.stringify(data).substring(0, 50)}...`);
              
              if (data.chunk) {
                // 检查消息是否仍然存在
                if (messageIndex < localMessages.value.length) {
                  // 检查是否包含无效字符
                  const cleanChunk = data.chunk
                    .replace(/[\uFFFD\uFFFE\uFFFF]/g, '') // 替换无效Unicode字符
                    .replace(/\u0000/g, ''); // 替换NULL字符
                  
                  // 标记已收到内容
                  receivedAnyContent = true;
                  
                  // 累积文本块，减少更新频率
                  accumulatedChunks += cleanChunk;
                  fullResponse += cleanChunk;
                  updateCounter++;
                  
                  // 每3个块或累积超过30个字符才更新一次UI
                  if (updateCounter % 3 === 0 || accumulatedChunks.length > 30) {
                    // 直接修改当前消息的内容，而不是整个消息对象
                    localMessages.value[messageIndex].content += accumulatedChunks;
                    localMessages.value[messageIndex].isStreaming = true;
                    console.log(`更新UI，添加了 ${accumulatedChunks.length} 个字符`);
                    accumulatedChunks = ''; // 重置累积块
                    
                    // 更新父组件消息 - 使用函数形式传递，减少不必要的响应式更新
                    emit('update-messages', [...localMessages.value]);
                    
                    // 强制滚动到底部
                    await nextTick(() => {
                      const container = document.querySelector('.chat-messages');
                      if (container) {
                        container.scrollTop = container.scrollHeight;
                      }
                    });
                  }
                }
              } else if (data.done) {
                console.log('收到完成标记');
                // 流式输出完成，添加任何剩余的累积文本
                if (accumulatedChunks.length > 0 && messageIndex < localMessages.value.length) {
                  localMessages.value[messageIndex].content += accumulatedChunks;
                  console.log(`添加剩余累积文本: ${accumulatedChunks.length} 个字符`);
                }
                
                // 如果服务器返回了完整响应，使用它来替换当前内容
                if (data.full_response && messageIndex < localMessages.value.length) {
                  // 清理完整响应中的无效字符
                  const cleanResponse = data.full_response
                    .replace(/[\uFFFD\uFFFE\uFFFF]/g, '')
                    .replace(/\u0000/g, '');
                  localMessages.value[messageIndex].content = cleanResponse;
                  console.log(`使用完整响应替换内容，长度: ${cleanResponse.length} 个字符`);
                }
                
                // 流式输出完成
                if (messageIndex < localMessages.value.length) {
                  localMessages.value[messageIndex].isStreaming = false;
                  // 添加来源信息
                  if (sources && sources.length > 0) {
                    localMessages.value[messageIndex].sources = sources;
                  }
                  emit('update-messages', [...localMessages.value]);
                  console.log(`流式输出完成，最终消息长度: ${localMessages.value[messageIndex].content.length} 字符`);
                  
                  // 强制滚动到底部
                  await nextTick(() => {
                    const container = document.querySelector('.chat-messages');
                    if (container) {
                      container.scrollTop = container.scrollHeight;
                    }
                  });
                }
                return data.full_response || fullResponse;
              } else if (data.error) {
                console.error(`收到错误: ${data.error}`);
                throw new Error(data.error);
              } else {
                // 处理可能的原始文本响应
                if (typeof data === 'string' && data.trim()) {
                  receivedAnyContent = true;
                  accumulatedChunks += data.trim();
                  fullResponse += data.trim();
                  updateCounter++;
                  
                  if (updateCounter % 3 === 0 || accumulatedChunks.length > 30) {
                    localMessages.value[messageIndex].content += accumulatedChunks;
                    localMessages.value[messageIndex].isStreaming = true;
                    accumulatedChunks = '';
                    emit('update-messages', [...localMessages.value]);
                  }
                }
              }
            } catch (e) {
              console.error('解析事件数据失败:', e, line);
              // 尝试作为纯文本处理
              if (line.substring(6).trim()) {
                const textContent = line.substring(6).trim();
                accumulatedChunks += textContent;
                fullResponse += textContent;
                receivedAnyContent = true;
                
                localMessages.value[messageIndex].content += textContent;
                localMessages.value[messageIndex].isStreaming = true;
                emit('update-messages', [...localMessages.value]);
              }
            }
          } else if (line.trim()) {
            // 处理非标准格式的行
            console.log(`收到非标准格式行: ${line.substring(0, 50)}...`);
            accumulatedChunks += line.trim() + "\n";
            fullResponse += line.trim() + "\n";
            receivedAnyContent = true;
            
            localMessages.value[messageIndex].content += line.trim() + "\n";
            localMessages.value[messageIndex].isStreaming = true;
            emit('update-messages', [...localMessages.value]);
          }
        }
      }
    } catch (streamError) {
      console.error('读取流错误:', streamError);
      
      // 如果已经有一些内容，则显示并标记为完成
      if (fullResponse || accumulatedChunks) {
        const finalContent = fullResponse + accumulatedChunks;
        if (messageIndex < localMessages.value.length) {
          localMessages.value[messageIndex].content = finalContent;
          localMessages.value[messageIndex].isStreaming = false;
          emit('update-messages', [...localMessages.value]);
        }
        return finalContent;
      } else {
        // 如果没有内容，则显示错误
        throw streamError;
      }
    }
    
    // 如果到这里，说明流结束但没有收到done事件
    console.log('流结束，但未收到完成标记');
    
    // 添加任何剩余的累积文本
    if (accumulatedChunks.length > 0 && messageIndex < localMessages.value.length) {
      localMessages.value[messageIndex].content += accumulatedChunks;
      console.log(`添加最终剩余文本: ${accumulatedChunks.length} 个字符`);
    }
    
    // 如果没有收到任何内容，但是处理了音频文件
    if (!receivedAnyContent && fullResponse === '') {
      console.log('未收到任何内容，检查是否为音频处理');
      
      // 检查消息内容是否已经被设置为音频处理结果
      if (messageIndex < localMessages.value.length) {
        const currentContent = localMessages.value[messageIndex].content;
        
        // 如果消息内容为空或仍然是处理中的提示，则设置默认消息
        if (!currentContent || 
            currentContent === '正在处理音频，请稍候...' ||
            currentContent === '正在处理会议录音，请稍候...') {
          
          // 直接使用后端返回的响应，不再使用默认消息
          const responseText = await response.text();
          localMessages.value[messageIndex].content = responseText || '音频处理完成，但服务器未返回任何内容。';
          localMessages.value[messageIndex].isStreaming = false;
          emit('update-messages', [...localMessages.value]);
          console.log('设置音频处理结果');
          return responseText || '';
        } else {
          console.log('消息内容已被设置，保留现有内容');
          localMessages.value[messageIndex].isStreaming = false;
          emit('update-messages', [...localMessages.value]);
          return currentContent;
        }
      }
    }
    
    if (messageIndex < localMessages.value.length) {
      localMessages.value[messageIndex].isStreaming = false;
      // 添加来源信息
      if (sources && sources.length > 0) {
        localMessages.value[messageIndex].sources = sources;
      }
      
      // 如果内容为空或仍然是"正在处理..."，设置一个默认消息
      if (!localMessages.value[messageIndex].content || 
          localMessages.value[messageIndex].content === '正在处理音频，请稍候...' ||
          localMessages.value[messageIndex].content === '正在处理会议录音，请稍候...') {
        // 直接使用后端返回的响应
        const responseText = await response.text();
        localMessages.value[messageIndex].content = responseText || '音频处理完成，但服务器未返回任何内容。';
      }
      
      emit('update-messages', [...localMessages.value]);
      console.log(`流处理结束，最终消息: ${localMessages.value[messageIndex].content.substring(0, 50)}...`);
    }
    return fullResponse;
    
  } catch (error) {
    console.error('Stream request error:', error);
    
    // 更新消息内容为错误信息
    if (messageIndex < localMessages.value.length) {
      localMessages.value[messageIndex].content = `抱歉，请求失败: ${error.message}`;
      localMessages.value[messageIndex].isStreaming = false;
      localMessages.value[messageIndex].isError = true;
      emit('update-messages', [...localMessages.value]);
    } else {
      // 如果消息索引无效，创建一个新的错误消息
      localMessages.value.push({
        type: 'assistant',
        content: `抱歉，请求失败: ${error.message}`,
        timestamp: new Date().toISOString(),
        isError: true
      });
      emit('update-messages', localMessages.value);
    }
    return '';
  }
}

// 处理流式响应
const handleStreamingResponse = async (endpoint, messageData, messageIndex, feature) => {
  try {
    const isStreaming = true; // 本地变量，标记正在流式输出
    const response = await fetch(`http://localhost:5000/${endpoint}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(messageData),
    });

    if (!response.ok) {
      const errorData = await response.json();
      console.error('Stream error:', errorData);
      // 错误处理
      if (localMessages.value[messageIndex]) {
        localMessages.value[messageIndex].content = `请求失败: ${errorData.error || response.statusText}`;
        localMessages.value[messageIndex].isStreaming = false;
        localMessages.value[messageIndex].isError = true;
        emit('update-messages', localMessages.value);
      }
      return;
    }

    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let partialResponse = '';
    let completedResponses = {}; // 存储完整响应的本地对象

    // 确保消息数组中有此索引的消息
    if (!localMessages.value[messageIndex]) {
      console.error(`消息索引 ${messageIndex} 不存在`);
      return;
    }

    localMessages.value[messageIndex].content = '';
    localMessages.value[messageIndex].isStreaming = true;
    emit('update-messages', localMessages.value);

    let charDelay = 0; // 字符延迟计数器
    
    while (true) {
      const { done, value } = await reader.read();

      if (done) {
        break;
      }

      // 解码当前块
      const chunk = decoder.decode(value, { stream: true });
      partialResponse += chunk;

      // 逐字符添加内容，实现打字机效果
      for (let i = 0; i < chunk.length; i++) {
        // 每隔几个字符才更新一次，减少重绘次数
        charDelay++;
        if (charDelay % 2 === 0) { // 每2个字符更新一次
          if (i + 2 <= chunk.length) {
            localMessages.value[messageIndex].content += chunk.substring(i, i+2);
            i++; // 跳过下一个字符
          } else {
            localMessages.value[messageIndex].content += chunk.substring(i);
          }
          
          // 发出更新事件
          emit('update-messages', localMessages.value);
          
          // 添加延迟，实现更明显的打字机效果
          await new Promise(resolve => setTimeout(resolve, 10)); // 10ms延迟
        }
      }

      // 保存完整响应以备后用
      completedResponses[messageIndex] = partialResponse;
      
      // 自动滚动到底部
      await nextTick(() => {
        const container = document.querySelector('.chat-messages');
        if (container) {
          container.scrollTop = container.scrollHeight;
        }
      });
    }

    // 确保最终内容是完整的（防止有字符遗漏）
    if (localMessages.value[messageIndex]) {
      localMessages.value[messageIndex].content = partialResponse;
      localMessages.value[messageIndex].isStreaming = false;
      
      // 更新完整响应缓存
      completedResponses[messageIndex] = partialResponse;
      
      // 更新父组件消息
      emit('update-messages', localMessages.value);
    }
  } catch (error) {
    console.error('流式处理错误:', error);
    
    // 恢复流式消息的状态
    if (localMessages.value[messageIndex]) {
      localMessages.value[messageIndex].content = `处理响应时出错: ${error.message}`;
      localMessages.value[messageIndex].isStreaming = false;
      localMessages.value[messageIndex].isError = true;
      emit('update-messages', localMessages.value);
    }
  }
};

// 切换模型
const changeModel = (modelId) => {
  selectedModel.value = modelId
  localMessages.value.push({
    type: 'assistant',
    content: `已切换至 ${availableModels.find(m => m.id === modelId).name} 模型`,
    timestamp: new Date().toISOString()
  })
  
  // 更新父组件的消息
  emit('update-messages', localMessages.value)
}

// 处理文件上传 - 旧方法，保留用于兼容性
const handleFileUpload = async (event) => {
  const file = event.target.files[0]
  if (!file) return
  
  const token = localStorage.getItem('token')
  if (!token) {
    localMessages.value.push({
      type: 'assistant',
      content: '请先登录以使用文件上传功能。',
      timestamp: new Date().toISOString()
    })
    emit('update-messages', localMessages.value)
    return
  }
  
  // 处理图片文件
  if (file.type.startsWith('image/')) {
    const reader = new FileReader()
    reader.onload = async (e) => {
      // 添加用户消息（图片）
      localMessages.value.push({
        type: 'user',
        content: `![上传的图片](${e.target.result})`,
        timestamp: new Date().toISOString(),
        isImage: true
      })
      
      // 更新父组件的消息
      emit('update-messages', localMessages.value)
      
      try {
        // 发送图片到后端
        const formData = new FormData()
        formData.append('file', file)
        formData.append('message', '请分析这张图片')
        formData.append('conversation_id', props.conversationId)
        formData.append('model', selectedModel.value)
        
        const response = await fetch(`${API_BASE_URL}/chat`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${token}`
          },
          body: formData
        })
        
        if (!response.ok) {
          throw new Error('Image upload failed')
        }
        
        const data = await response.json()
        
        // 添加助手回复
        localMessages.value.push({
          type: 'assistant',
          content: data.response,
          timestamp: new Date().toISOString()
        })
        
        // 更新父组件的消息
        emit('update-messages', localMessages.value)
      } catch (error) {
        console.error('Error uploading image:', error)
        
        // 添加错误消息
        localMessages.value.push({
          type: 'assistant',
          content: '抱歉，图片处理失败。请稍后再试。',
          timestamp: new Date().toISOString()
        })
        
        // 更新父组件的消息
        emit('update-messages', localMessages.value)
      }
    }
    reader.readAsDataURL(file)
  } else if (props.currentPage === 'knowledge' && (file.type === 'application/pdf' || file.type === 'application/msword' || file.type === 'text/plain' || file.name.endsWith('.docx') || file.name.endsWith('.pdf'))) {
    // 如果是知识库页面且是PDF或文档文件，则上传到知识库
    try {
      // 添加上传中提示
      const uploadingMessageIndex = localMessages.value.length;
      localMessages.value.push({
        type: 'assistant',
        content: `正在处理文件 ${file.name}，请稍候...`,
        timestamp: new Date().toISOString(),
        isLoading: true
      });
      emit('update-messages', localMessages.value);
      
      const formData = new FormData()
      formData.append('file', file)
      formData.append('name', file.name)
      formData.append('description', '用户上传的知识库文件')
      
      const response = await fetch(`${API_BASE_URL}/knowledge/upload`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${token}`
        },
        body: formData
      })
      
      if (!response.ok) {
        throw new Error('知识库上传失败')
      }
      
      const data = await response.json()
      
      // 保存知识库ID
      localStorage.setItem('selectedKnowledgeBase', data.kb_id)
      
      // 添加用户消息
      localMessages.value.push({
        type: 'user',
        content: `上传了知识库文件: ${file.name}`,
        timestamp: new Date().toISOString()
      })
      
      // 更新上传中消息为成功消息
      if (uploadingMessageIndex < localMessages.value.length) {
        localMessages.value[uploadingMessageIndex] = {
        type: 'assistant',
          content: `✅ 知识库文件 ${file.name} 上传成功！\n\n文件已被分割成多个文本块并存入向量数据库。您现在可以开始查询这个知识库了，例如：\n\n- "这个文档主要讲了什么？"\n- "总结一下文档的关键内容"\n- "文档中有哪些重要的观点？"`,
        timestamp: new Date().toISOString()
        };
      }
      
      // 更新父组件的消息
      emit('update-messages', localMessages.value)
    } catch (error) {
      console.error('Error uploading knowledge base:', error)
      
      // 添加错误消息
      localMessages.value.push({
        type: 'assistant',
        content: `❌ 知识库文件上传失败: ${error.message}。请确保文件格式正确且大小合适。`,
        timestamp: new Date().toISOString(),
        isError: true
      })
      
      // 更新父组件的消息
      emit('update-messages', localMessages.value)
    }
  } else {
    // 处理其他类型文件
    localMessages.value.push({
      type: 'user',
      content: `上传了文件: ${file.name}`,
      timestamp: new Date().toISOString()
    })
    
    // 添加助手回复
    localMessages.value.push({
      type: 'assistant',
      content: `我已收到你上传的文件 ${file.name}，但目前我只能处理图片和PDF/Word文档。如果您想创建知识库，请上传PDF、Word文档或文本文件。`,
      timestamp: new Date().toISOString()
    })
    
    // 更新父组件的消息
    emit('update-messages', localMessages.value)
  }
  
  // 清空文件输入，以便可以再次上传相同的文件
  event.target.value = ''
}

// 处理来自FileUploader组件的文件选择
const handleFileSelected = async (fileData) => {
  const token = localStorage.getItem('token')
  if (!token) {
    localMessages.value.push({
      type: 'assistant',
      content: '请先登录以使用文件上传功能。',
      timestamp: new Date().toISOString()
    })
    emit('update-messages', localMessages.value)
    return
  }
  selectedFile.value = fileData
  try {
    if (props.currentPage === 'meeting') {
      if (fileData.type === 'application/pdf' || 
          fileData.type === 'application/msword' || 
          fileData.type === 'text/plain' || 
          fileData.name.endsWith('.docx') || 
          fileData.name.endsWith('.pdf')) {
        // 会议文档上传
        localMessages.value.push({
          type: 'user',
          content: `[上传了文件: ${fileData.name}]`,
          timestamp: new Date().toISOString()
        })
        emit('update-messages', localMessages.value)
        await uploadMeetingFile(fileData)
      } else if (fileData.type.startsWith('audio/')) {
        // 会议录音处理
        localMessages.value.push({
          type: 'user',
          content: `[上传了音频: ${fileData.name}]`,
          timestamp: new Date().toISOString()
        })
        emit('update-messages', localMessages.value)
        await handleMeetingContent(`data:${fileData.type};base64,${fileData.base64}`, 'audio')
      } else {
        throw new Error('不支持的文件类型')
      }
    } else if (fileData.type.startsWith('image/')) {
      localMessages.value.push({
        type: 'user',
        content: `[上传了图片: ${fileData.name}]`,
        timestamp: new Date().toISOString()
      })
      emit('update-messages', localMessages.value)
      await handleImageFile(fileData)
    } else if (fileData.type.startsWith('audio/')) {
      localMessages.value.push({
        type: 'user',
        content: `[上传了音频: ${fileData.name}]`,
        timestamp: new Date().toISOString()
      })
      emit('update-messages', localMessages.value)
      await handleAudioFile(fileData)
    } else if (props.currentPage === 'knowledge' && 
              (fileData.type === 'application/pdf' || 
               fileData.type === 'application/msword' || 
               fileData.type === 'text/plain' || 
               fileData.name.endsWith('.docx') || 
               fileData.name.endsWith('.pdf'))) {
      localMessages.value.push({
        type: 'user',
        content: `[上传了文件: ${fileData.name}]`,
        timestamp: new Date().toISOString()
      })
      emit('update-messages', localMessages.value)
      await handleKnowledgeFile(fileData)
    } else {
      localMessages.value.push({
        type: 'user',
        content: `[上传了文件: ${fileData.name}]`,
        timestamp: new Date().toISOString()
      })
      emit('update-messages', localMessages.value)
      await handleOtherFile(fileData)
    }
  } catch (error) {
    console.error('文件处理失败:', error)
    localMessages.value.push({
      type: 'assistant',
      content: `文件处理失败: ${error.message}`,
      timestamp: new Date().toISOString(),
      isError: true
    })
    emit('update-messages', localMessages.value)
  }
}

// 处理图片文件
const handleImageFile = async (fileData) => {
  // 显示图片预览
  const imagePreview = `data:${fileData.type};base64,${fileData.base64}`
  
  // 添加用户消息（图片）
  localMessages.value.push({
    type: 'user',
    content: `![上传的图片](${imagePreview})`,
    timestamp: new Date().toISOString(),
    isImage: true
  })
  
  // 更新父组件的消息
  emit('update-messages', localMessages.value)
  
  try {
    // 准备发送给模型的数据
    const token = localStorage.getItem('token')
    
    // 为Qwen-Omni-Turbo模型准备特殊格式
    const requestData = {
      message: selectedModel.value === 'qianwen' ? 
        // 如果是通义千问模型，使用特殊格式
        {
          role: "user",
          content: [
            {
              type: "image_url",
              image_url: {
                url: `data:${fileData.type};base64,${fileData.base64}`
              }
            },
            {
              type: "text",
              text: "请分析这张图片"
            }
          ]
        } : 
        // 否则使用普通文本
        '请分析这张图片',
      conversation_id: props.conversationId,
      model: selectedModel.value,
      file_data: {
        name: fileData.name,
        type: fileData.type,
        base64: fileData.base64
      }
    }
    
    // 发送请求
    const response = await fetch(`${API_BASE_URL}/chat/stream`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
      },
      body: JSON.stringify(requestData)
    })
    
    if (!response.ok) {
      throw new Error('图片处理失败')
    }
    
    // 处理流式响应
    const messageIndex = localMessages.value.length
    localMessages.value.push({
      type: 'assistant',
      content: '',
      timestamp: new Date().toISOString(),
      isStreaming: true
    })
    
    // 更新父组件消息
    emit('update-messages', localMessages.value)
    
    // 处理流式响应
    await processStreamResponse(response, messageIndex)
    
  } catch (error) {
    console.error('Error processing image:', error)
    
    // 添加错误消息
    localMessages.value.push({
      type: 'assistant',
      content: `抱歉，图片处理失败: ${error.message}`,
      timestamp: new Date().toISOString(),
      isError: true
    })
    
    // 更新父组件的消息
    emit('update-messages', localMessages.value)
  }
}

// 处理音频文件
const handleAudioFile = async (fileData) => {
  // 在非会议记录页面添加用户消息（音频）
  if (props.currentPage !== 'meeting') {
    localMessages.value.push({
      type: 'user',
      content: `[上传了音频文件: ${fileData.name}]`,
      timestamp: new Date().toISOString()
    })
    emit('update-messages', localMessages.value)
  }
  
  try {
    const token = localStorage.getItem('token')
    
    // 创建或获取消息索引
    let messageIndex
    if (props.currentPage !== 'meeting') {
      messageIndex = localMessages.value.length
      localMessages.value.push({
        type: 'assistant',
        content: '正在处理音频，请稍候...',
        timestamp: new Date().toISOString(),
        isStreaming: true
      })
      emit('update-messages', localMessages.value)
    } else {
      messageIndex = localMessages.value.length - 1
    }

    // 准备请求数据
    const requestData = {
      messages: [
        {
          role: "system",
          content: [{ text: "You are a helpful assistant." }]
        },
        {
          role: "user",
          content: [
            { audio: `data:${fileData.type};base64,${fileData.base64}` },
            { text: props.currentPage === 'meeting' ? 
              "这是一段会议录音，请帮我转录并总结会议内容，提取关键讨论点、决策和行动项目。" :
              "音频里在说什么?" 
            }
          ]
        }
      ],
      model: "qwen-audio-turbo-latest",
      conversation_id: props.conversationId
    }

    // 发送请求到音频识别接口
    const response = await fetchWithRetry(`${API_BASE_URL}/audio/recognize`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
      },
      body: JSON.stringify(requestData)
    })

    if (!response.ok) {
      throw new Error(`音频处理失败: ${response.status} ${response.statusText}`)
    }

    // 读取响应内容
    const data = await response.json()
    
    // 更新消息内容
    if (messageIndex >= 0 && messageIndex < localMessages.value.length) {
      // 检查并显示识别结果
      if (data.output?.choices?.[0]?.message?.content?.[0]?.text) {
        localMessages.value[messageIndex].content = data.output.choices[0].message.content[0].text
      } else if (data.response) {
        localMessages.value[messageIndex].content = data.response
      } else {
        localMessages.value[messageIndex].content = '音频处理完成，但未能获取识别结果'
      }
      localMessages.value[messageIndex].isStreaming = false
      emit('update-messages', [...localMessages.value])
    }

  } catch (error) {
    console.error('音频处理失败:', error)
    
    // 更新错误消息
    if (messageIndex >= 0 && messageIndex < localMessages.value.length) {
      localMessages.value[messageIndex].content = `音频处理失败: ${error.message}`
      localMessages.value[messageIndex].isStreaming = false
      localMessages.value[messageIndex].isError = true
      emit('update-messages', [...localMessages.value])
    } else {
      localMessages.value.push({
        type: 'assistant',
        content: `音频处理失败: ${error.message}`,
        timestamp: new Date().toISOString(),
        isError: true
      })
      emit('update-messages', localMessages.value)
    }
  }
}

// 处理知识库文件
const handleKnowledgeFile = async (fileData) => {
  try {
    // 添加上传中提示
    const uploadingMessageIndex = localMessages.value.length
    localMessages.value.push({
      type: 'assistant',
      content: `正在处理文件 ${fileData.name}，请稍候...`,
      timestamp: new Date().toISOString(),
      isLoading: true
    })
    emit('update-messages', localMessages.value)
    
    const token = localStorage.getItem('token')
    const formData = new FormData()
    
    // 将base64转回文件对象
    const byteCharacters = atob(fileData.base64)
    const byteNumbers = new Array(byteCharacters.length)
    for (let i = 0; i < byteCharacters.length; i++) {
      byteNumbers[i] = byteCharacters.charCodeAt(i)
    }
    const byteArray = new Uint8Array(byteNumbers)
    const blob = new Blob([byteArray], { type: fileData.type })
    
    formData.append('file', blob, fileData.name)
    formData.append('name', fileData.name)
    formData.append('description', '用户上传的知识库文件')
    
    const response = await fetch(`${API_BASE_URL}/knowledge/upload`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`
      },
      body: formData
    })
    
    if (!response.ok) {
      throw new Error('知识库上传失败')
    }
    
    const data = await response.json()
    
    // 保存知识库ID
    localStorage.setItem('selectedKnowledgeBase', data.kb_id)
    
    // 添加用户消息
    localMessages.value.push({
      type: 'user',
      content: `上传了知识库文件: ${fileData.name}`,
      timestamp: new Date().toISOString()
    })
    
    // 更新上传中消息为成功消息
    if (uploadingMessageIndex < localMessages.value.length) {
      localMessages.value[uploadingMessageIndex] = {
        type: 'assistant',
        content: `✅ 知识库文件 ${fileData.name} 上传成功！\n\n文件已被分割成多个文本块并存入向量数据库。您现在可以开始查询这个知识库了，例如：\n\n- "这个文档主要讲了什么？"\n- "总结一下文档的关键内容"\n- "文档中有哪些重要的观点？"`,
        timestamp: new Date().toISOString()
      }
    }
    
    // 更新父组件的消息
    emit('update-messages', localMessages.value)
  } catch (error) {
    console.error('Error uploading knowledge base:', error)
    
    // 添加错误消息
    localMessages.value.push({
      type: 'assistant',
      content: `❌ 知识库文件上传失败: ${error.message}。请确保文件格式正确且大小合适。`,
      timestamp: new Date().toISOString(),
      isError: true
    })
    
    // 更新父组件的消息
    emit('update-messages', localMessages.value)
  }
}

// 处理其他类型文件
const handleOtherFile = async (fileData) => {
  // 添加用户消息
  localMessages.value.push({
    type: 'user',
    content: `[上传了文件: ${fileData.name}]`,
    timestamp: new Date().toISOString()
  })
  
  // 更新父组件的消息
  emit('update-messages', localMessages.value)
  
  try {
    // 准备发送给模型的数据
    const token = localStorage.getItem('token')
    const requestData = {
      message: `请分析这个文件: ${fileData.name}`,
      conversation_id: props.conversationId,
      model: selectedModel.value,
      file_data: {
        name: fileData.name,
        type: fileData.type,
        base64: fileData.base64
      }
    }
    
    // 发送请求
    const response = await fetch(`${API_BASE_URL}/chat/stream`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
      },
      body: JSON.stringify(requestData)
    })
    
    if (!response.ok) {
      throw new Error('文件处理失败')
    }
    
    // 处理流式响应
    const messageIndex = localMessages.value.length
    localMessages.value.push({
      type: 'assistant',
      content: '',
      timestamp: new Date().toISOString(),
      isStreaming: true
    })
    
    // 更新父组件消息
    emit('update-messages', localMessages.value)
    
    // 处理流式响应
    await processStreamResponse(response, messageIndex)
    
  } catch (error) {
    console.error('Error processing file:', error)
    
    // 添加错误消息
    localMessages.value.push({
      type: 'assistant',
      content: `抱歉，文件处理失败: ${error.message}`,
      timestamp: new Date().toISOString(),
      isError: true
    })
    
    // 更新父组件的消息
    emit('update-messages', localMessages.value)
  }
}

// 处理语音输入
const startVoiceInput = () => {
  if (!('webkitSpeechRecognition' in window)) {
    alert('您的浏览器不支持语音识别功能')
    return
  }
  
  const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition
  const recognition = new SpeechRecognition()
  
  recognition.lang = 'zh-CN'
  recognition.interimResults = false
  recognition.maxAlternatives = 1
  
  recognition.start()
  
  recognition.onresult = (event) => {
    const transcript = event.results[0][0].transcript
    userInput.value = transcript
  }
  
  recognition.onerror = (event) => {
    console.error('语音识别错误:', event.error)
    alert('语音识别失败: ' + event.error)
  }
}

// 处理热门话题点击
const handleTopicSelect = (topic) => {
  userInput.value = topic
  handleSendMessage(userInput.value)
}

// 监听页面变化
watch(() => props.currentPage, (newPage) => {
  localMessages.value = []
  
  // 添加欢迎消息
  const welcomeMessages = {
    chat: '你好！我是多功能智能助手，可以回答问题、提供知识、规划任务、进行情感交流、健康咨询以及文化学习。有什么我可以帮到你的吗？',
    weather: '欢迎使用天气查询功能。请输入城市名称，我会为你查询天气信息。',
    knowledge: '欢迎使用知识库问答功能。你可以上传PDF、TXT或DOCX文件创建个人知识库，然后询问相关问题，我会基于你的知识库内容回答。',
    task: '欢迎使用任务规划功能。你可以创建任务，例如："创建一个明天下午3点提交报告的任务"，我会帮你设置任务和提醒。',
    health: '欢迎使用健康咨询功能。我可以提供一般性的健康建议，但请记住我不是专业医生，严重问题请咨询医疗专业人士。',
    meeting: '欢迎使用会议记录功能。你可以上传会议文档(PDF、TXT或DOCX)或会议录音文件(MP3、WAV等)，或直接输入会议内容，我会帮你整理会议要点、提取行动项目并生成会议总结。音频文件将使用千问大模型进行处理。'
  }
  
  if (welcomeMessages[newPage]) {
    localMessages.value.push({
      type: 'assistant',
      content: welcomeMessages[newPage],
      timestamp: new Date().toISOString()
    })
    
    // 更新父组件的消息
    emit('update-messages', localMessages.value)
  }
})

// 更新消息内容的辅助函数 - 优化性能
const updateMessageContent = (messageIndex, content, isStreaming = false, isError = false, sources = []) => {
  if (messageIndex < localMessages.value.length) {
    // 直接修改对象属性，而不是替换整个对象
    localMessages.value[messageIndex].content = content;
    localMessages.value[messageIndex].isStreaming = isStreaming;
    localMessages.value[messageIndex].isError = isError;
    if (sources && sources.length > 0) {
      localMessages.value[messageIndex].sources = sources;
    }
    // 创建新数组引用，确保Vue检测到变化
    emit('update-messages', [...localMessages.value]);
  } else {
    // 如果消息索引无效，创建一个新的消息
    localMessages.value.push({
      type: 'assistant',
      content: content,
      timestamp: new Date().toISOString(),
      isStreaming: isStreaming,
      isError: isError,
      sources: sources
    });
    emit('update-messages', [...localMessages.value]);
  }
}

// 处理会议内容
const handleMeetingContent = async (content, contentType = 'text') => {
  let messageIndex;
  try {
    const token = localStorage.getItem('token')
    
    // 添加用户消息
    localMessages.value.push({
      type: 'user',
      content: contentType === 'audio' ? 
        `[上传了会议录音]` : 
        (contentType === 'document' ? 
          `[上传了会议文档]` : 
          content),
      timestamp: new Date().toISOString()
    })
    
    // 更新父组件的消息
    emit('update-messages', localMessages.value)
    
    // 添加处理中的消息
    messageIndex = localMessages.value.length
    localMessages.value.push({
      type: 'assistant',
      content: contentType === 'audio' ? '正在处理会议录音，请稍候...' : '正在处理会议内容，请稍候...',
      timestamp: new Date().toISOString(),
      isStreaming: true
    })
    
    // 更新父组件消息
    emit('update-messages', localMessages.value)
    
    // 构造请求体
    let requestBody;
    if (contentType === 'audio') {
      requestBody = {
        content_type: 'audio',
        message: {
          role: 'user',
          content: [
            { audio: content },
            { text: '请分析这段会议录音' }
          ]
        },
        model: selectedModel.value
      }
    } else {
      requestBody = {
        content: content,
        content_type: contentType,
        model: selectedModel.value
      }
    }
    
    // 发送请求
    const response = await fetchWithRetry(`${API_BASE_URL}/meeting/process`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
      },
      body: JSON.stringify(requestBody)
    })
    
    if (!response.ok) {
      const errorData = await response.json()
      throw new Error(errorData.error || '会议处理请求失败')
    }
    
    // 处理响应
    if (contentType === 'audio') {
      // 音频处理使用非流式响应
      const data = await response.json()
      if (data.output?.choices?.[0]?.message?.content?.[0]?.text) {
        updateMessageContent(messageIndex, data.output.choices[0].message.content[0].text, false)
      } else if (data.response) {
        updateMessageContent(messageIndex, data.response, false)
      } else {
        updateMessageContent(messageIndex, '会议处理完成，但未能获取处理结果', false, true)
      }
    } else {
      // 文本处理使用流式响应
      await processStreamResponse(response, messageIndex)
    }
    
  } catch (error) {
    console.error('会议处理失败:', error)
    
    // 使用辅助函数更新错误消息
    updateMessageContent(
      messageIndex,
      `会议处理失败: ${error.message}`,
      false,
      true
    )
  }
}

// 会议多轮问答历史
const meetingHistory = ref([])

// 上传会议文档
const uploadMeetingFile = async (fileData) => {
  const token = localStorage.getItem('token')
  const formData = new FormData()
  // base64转文件对象
  const byteCharacters = atob(fileData.base64)
  const byteNumbers = new Array(byteCharacters.length)
  for (let i = 0; i < byteCharacters.length; i++) {
    byteNumbers[i] = byteCharacters.charCodeAt(i)
  }
  const byteArray = new Uint8Array(byteNumbers)
  const blob = new Blob([byteArray], { type: fileData.type })
  formData.append('file', blob, fileData.name)

  const response = await fetch(`${API_BASE_URL}/meeting/upload`, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${token}` },
    body: formData
  })
  if (!response.ok) throw new Error('会议文档上传失败')
  const data = await response.json()
  localStorage.setItem('meeting_id', data.meeting_id)
  meetingHistory.value = [] // 新会议清空历史
  localMessages.value.push({
    type: 'assistant',
    content: `会议文档已上传，全部内容如下：\n\n${data.content}`,
    timestamp: new Date().toISOString()
  })
  emit('update-messages', localMessages.value)
}

// 会议内容多轮问答
const askMeetingQuestion = async (question) => {
  const token = localStorage.getItem('token')
  const meeting_id = localStorage.getItem('meeting_id')
  if (!meeting_id) {
    errorMessage.value = '请先上传会议文档'
    return
  }
  localMessages.value.push({
    type: 'user',
    content: question,
    timestamp: new Date().toISOString()
  })
  emit('update-messages', localMessages.value)
  const messageIndex = localMessages.value.length
  localMessages.value.push({
    type: 'assistant',
    content: '正在分析会议内容，请稍候...',
    timestamp: new Date().toISOString(),
    isStreaming: true
  })
  emit('update-messages', localMessages.value)
  const response = await fetch(`${API_BASE_URL}/meeting/qa`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({
      meeting_id,
      question,
      history: meetingHistory.value
    })
  })
  const data = await response.json()
  if (data.answer) {
    localMessages.value[messageIndex].content = data.answer
    localMessages.value[messageIndex].isStreaming = false
    meetingHistory.value = data.history
    emit('update-messages', localMessages.value)
  } else {
    localMessages.value[messageIndex].content = `会议问答失败: ${data.error || '未知错误'}`
    localMessages.value[messageIndex].isStreaming = false
    emit('update-messages', localMessages.value)
  }
}
</script>

<template>
  <div class="bg-white rounded-lg shadow-sm h-[calc(100vh-8rem)] flex flex-col">
    <!-- 聊天消息区域 -->
    <div class="flex-grow overflow-y-auto p-6 chat-messages">
      <div class="flex gap-6 max-w-full">
        <!-- 左侧消息区域 -->
        <div class="flex-grow overflow-hidden">
          <div class="max-w-4xl mx-auto">
            <Message
              v-for="(message, index) in localMessages"
              :key="index"
              :type="message.type"
              :content="message.content"
              :timestamp="message.timestamp"
              :is-streaming="message.isStreaming || false"
              :is-error="message.isError || false"
              :sources="message.sources"
            />
          
            <!-- 错误消息 -->
            <div v-if="errorMessage" class="bg-red-50 text-red-500 p-3 rounded-lg mb-4 text-sm">
              {{ errorMessage }}
            </div>
          </div>
        </div>
        
        <!-- 右侧热门话题区域 -->
        <div class="w-64 flex-shrink-0">
          <TrendingTopics 
            :page-type="currentPage"
            @select-topic="handleTopicSelect"
          />
        </div>
      </div>
    </div>
    
    <!-- 输入区域 -->
    <div class="border-t border-gray-100 p-4">
      <!-- 模型选择器 -->
      <div class="flex items-center mb-3 gap-2">
        <span class="text-sm text-gray-500">模型:</span>
        <div class="flex gap-2">
          <button
            v-for="model in availableModels"
            :key="model.id"
            :class="[
              'px-3 py-1 rounded-full text-xs font-medium transition-colors flex items-center gap-1',
              selectedModel === model.id 
                ? 'bg-blue-100 text-blue-700 border border-blue-200' 
                : 'bg-gray-100 text-gray-600 hover:bg-gray-200 border border-transparent'
            ]"
            @click="changeModel(model.id)"
          >
            <i :class="['fas', model.icon]"></i>
            {{ model.name }}
          </button>
        </div>
      </div>
      
      <div class="flex items-center gap-3">
        <input
          v-model="userInput"
          type="text"
          :placeholder="'输入你的' + (
            currentPage === 'chat' ? '问题或请求' :
            currentPage === 'weather' ? '城市名称' :
            currentPage === 'knowledge' ? '知识问题' :
            currentPage === 'task' ? '任务内容' :
            currentPage === 'health' ? '健康问题' :
            currentPage === 'meeting' ? '会议内容或问题' :
            '问题'
          ) + '...'"
          class="flex-grow px-4 py-3 rounded-lg border border-gray-200 focus:outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-200 transition-all"
          @keyup.enter="handleSendMessage(userInput)"
        >
        
        <!-- 文件上传组件 -->
        <FileUploader 
          :current-page="currentPage"
          @file-selected="handleFileSelected"
        />
        
        <!-- 语音输入按钮 -->
        <button
          class="p-3 rounded-lg text-gray-500 hover:bg-gray-100 transition-colors"
          @click="startVoiceInput"
          title="语音输入"
        >
          <i class="fa fa-microphone"></i>
        </button>
        
        <!-- 发送按钮 -->
        <button
          class="bg-blue-500 text-white px-6 py-3 rounded-lg hover:bg-blue-600 transition-colors"
          @click="handleSendMessage(userInput)"
        >
          <i class="fa fa-paper-plane"></i>
        </button>
      </div>
    </div>
  </div>
</template>